 /*
  *@(#)IaaDebug.java		8 Sept. 2000
  *
  * Copyright: MetaPlus Inc & Inquiry Management Systems Ltd.  2000
  *
  * This software is the proprietary information of MetaPlus Inc & 
  * Inquiry Management Systems Ltd.  
  * Use is subject to license terms.
  */
package com.ims.iaa;

import java.util.*;
import java.io.*;
import java.sql.Timestamp;
import java.sql.Time;

/**
  * <p>Provide some constants frequently used in this package. These constants 
  * should be saved in a property file with name iaa.properties under the 
  * class file directory. A sample file is shipped with the program.</p>
  * If no iaa.properties were found, the system will exit.
  *
  * @author Anthony Zhang
  * @author ShengMeng Bai
  *
  * @version 1.00, 25 Sept. 2000
  * @version 2.00, 24 JUL. 2004
  *
  */
public class IaaDebug {
	/**
	  *
	  */
    public static final boolean processDebug;
	public static final boolean AuxDebug;
    public static final boolean ProDebug;
    public static final boolean AuxFileDebug;
    public static final boolean Debug;
    public static final boolean DatabaseDebug;

    public static final boolean StoreDB;
	public static final boolean ResultStoreDB;
	public static final boolean TimeoutKill;

	public static final String  ServerHost;
	public static final int ServerPort;
	
	//public static final boolean m_bProxySet;
	//public static final String m_sProxyHost;
	//public static final String m_sProxyPort;
	//public static final String m_sProxyUserName;
	//public static final String m_sProxyPassword;
	public static final boolean m_bRandomProxy;
	public static final int m_iProxyExpireSeconds;
	
	//add by ShengMengBai at 2005-04-30, 
	//because add the logic to process robots.txt for each site
	public static final String m_robotName;
	
	
	//25 Oct 2000 Anthony Zhang
//++************************modify by ShengMeng Bai at 2004-07-27
	/** 
	  * This field determine the interval that the spider should wait 
	  * between each page connect activity. The unit is in millisecond.
	  * It is read from the pageConnectInterval property in the iaa.properties file. 
	  * If not found, system will take the default value which is 1 second
	  * (1000 milliseconds).If the value is smaller than 500 millseconds the system will
	  * ignore the value in properties file and set it to 500, which is half second.
	  * 
	  * now, disuse PageConnectInterval, 
	  * replace wich iMinPageConnectInterval and iMaxPageConnectInterval,
	  * the default value of iMinPageConnectInterval is 1 second(1000 milliseconds).
	  * If the value is smaller than 500 millseconds the system will 
	  * ignore the value in properties file and set it to 500, which is half second.
	  * the default value of iMaxPageConnectInterval is 20 seconds(20000 milliseconds).
	  * If the value is bigger than 600000 millseconds (10 minutes), the system will
	  * ignore the value in properties file and set it to 600000, which is 10 minutes.
	  * 
	  * if iMinPageConnectInterval bigger than iMaxPageConnectInterval, 
	  * iMaxPageConnectInterval will be ignore, 
	  * and the interval is a constant value iMinPageConnectInterval.
	  */
//	public static final int PageConnectInterval;
	public static final int iMinPageConnectInterval;
	public static final int iMaxPageConnectInterval;
//--************************modify by ShengMeng Bai at 2004-07-27
		
	//4 Dec 2000 Anthony Zhang
	/** 
	  * This field determine the interval that the spider should wait 
	  * before it give up the one specific search. The unit is in second.
	  * It is read from the searchProcessTimeout property in the iaa.properties file. 
	  * If not found, system will take the default value which is 5 minutes(300 seconds).
	  * If the value is smaller than 300 seconds the system will
	  * ignore the value in properties file and set it to 500.
	  */
	public static final int SearchProcessTimeout;

	//20 Nov 2000 Anthony Zhang
	/** 
	  * This field determine whether the log information are written directly to the 
	  * screen (if the value is true) or stored into the log files(if the value is flase).
	  * It is read from the logWriteToScreen property in the iaa.properties file. 
	  * If not found, system will take the default value which is false.
	  */
	public static boolean LogWriteToScreen;	

	//20 Nov 2000 Anthony Zhang
	/** 
	  * This field determine the maximum line in the log file. Once the lines in the 
	  * log file reach the value. The log writer will creat a new log file.
	  * The unit is in line. It is read from the maxLineOfLog property in the 
	  * iaa.properties file. If not found, system will take the default value which is 
	  * 1000 lines. If the value is smaller than 500 the system will
	  * ignore the value in properties file and set it to 500 lines.
	  */
	public static final int MaxLineOfLog;
	
	//20 Nov 2000 Anthony Zhang
	/** 
	  * This field determine the maximum size of the image file which will be saved 
	  * the system. Image file exceed this value will not be saved. The unit is in byte.
	  * It is read from the maxImageSize property in the iaa.properties file. If not 
	  * found, system will take the default value which is 50KB(50000 bytes). If the 
	  * value is smaller than 5000 bytes the system will
	  * ignore the value in properties file and set it to 5000, which is 5KB.
	  */
	public static final int MaxImageSize;
	//if the image width < m_iMinImageWidth and image height < m_iMinImageHeight
	//IAA will don't save the image to database.
	public static final int m_iMinImageWidth;
	public static final int m_iMinImageHeight;
	//23 JUL 2004 ShengMeng Bai for flash
	/** 
	  * This field determine the maximum size of the flash file which will be saved 
	  * the system. flash file exceed this value will not be saved. The unit is in byte.
	  * It is read from the maxFlashSize property in the iaa.properties file. If not 
	  * found, system will take the default value which is 50KB(50000 bytes). If the 
	  * value is smaller than 5000 bytes the system will
	  * ignore the value in properties file and set it to 5000, which is 5KB.
	  */
	public static final int MaxFlashSize;
	
	public static final PrintStream systemout = System.out;
	public static final PrintStream systemerr = System.err;

	
	//26 Oct 2000 Anthony Zhang	
	/**
	  * This field is read from the logDirectory property in the iaa.properties file.
	  * The log directory can be either absolute path or relative path. Current path is 
	  * the directory where the server runs from. The log directory must be in correct 
	  * format and must exist, otherwise the log file will write to the subdirectory 
	  * named as <code>log</code> under the current directory.
	  * The format of the directory for Windows system is 
	  *  <code>d:\\temp\\logfile</code> which means absolute path d:\temp\logfile
	  * or 
	  *  <code>log</code> which means relative path log under current directory.
	  */ 
	public static final String LogDirectory;
	
	public static final boolean bAppointCrawlTime;
	public static final Time timeCrawlStartTime;
	public static final Time timeCrawlEndTime;
	
	/*
	 * because it need some time while connecting to ad resource (image, flash, applet),
	 * So need some seprate thread to connect to the resouce, 
	 * iaa.spiderAuxThread is the thread count, the valid range is form 2 to 10,
	 */
	public static final int m_iSpiderAuxThread;
	
	/*Sometime, it is failed while spider connect to a reource,
	* so IAA will re-connect to the resouce after m_iReConnectionInterval,
	* the unit of m_iReConnectionInterval is hours. 
	* The counter will increase 1 after IAA reconnect the resource,
	* m_iReConnectionTimes limited the maximal times, if the value of
	* the counter larger than m_iReConnectionTimes, IAA will don't reconnect it.
	*/
	//public static final int m_iReConnectionTimes;
	//public static final int m_iReConnectionInterval;
	
	//++changsheng 2006-5-16 for smart download
	public static final int SmartDownloadCounterMax ;
	//--

	public static final long pageAnalyzeTimeOut;
	
	static  {
	    Properties pro = new Properties();

	    try  {
	    	pro.load(new FileInputStream("iaa.properties"));
	    } catch (Exception e)  {
    		System.out.println("Fatal error: Can not open the iaa properties file");
			System.exit(3);
	    }
    	//pro.list(System.out);
   
	    
	    processDebug = Boolean.valueOf(
    			pro.getProperty("iaa.processInfo","false")).booleanValue();
	    
    	AuxDebug = Boolean.valueOf(
    			pro.getProperty("iaa.auxDebugInfo","false")).booleanValue();
    	
    	AuxFileDebug = Boolean.valueOf(
    			pro.getProperty("iaa.auxFileDebug","false")).booleanValue();

    	ProDebug = Boolean.valueOf(
    			pro.getProperty("iaa.proDebugInfo","false")).booleanValue();

		Debug = Boolean.valueOf(
				pro.getProperty("iaa.commonDebugInfo","false")).booleanValue();

    	DatabaseDebug = Boolean.valueOf(
    			pro.getProperty("iaa.DBDebugInfo","false")).booleanValue();

    	StoreDB = Boolean.valueOf(
				pro.getProperty("iaa.requestStoreInDB","true")).booleanValue();

	    ResultStoreDB = Boolean.valueOf(
				pro.getProperty("iaa.resultStoreInDB","true")).booleanValue();
		
		TimeoutKill = Boolean.valueOf(
				pro.getProperty("iaa.timeoutKill","true")).booleanValue();

		ServerHost = pro.getProperty("iaa.serverHost","localhost");
		
		ServerPort = Integer.parseInt(pro.getProperty("iaa.serverPort","1099"));
		
		LogWriteToScreen = Boolean.valueOf(
				pro.getProperty("iaa.logWriteToScreen","false")).booleanValue();

//++*************************Modify by ShengMeng Bai at 2004-07-27		
//		int interval = Integer.parseInt(pro.getProperty("iaa.pageConnectInterval","1000"));
//		PageConnectInterval = (interval < 500)?500:interval;
		int interval = Integer.parseInt(pro.getProperty("iaa.minPageConnectInterval","1000"));
		iMinPageConnectInterval = (interval < 500)?500:interval;
		interval = Integer.parseInt(pro.getProperty("iaa.maxPageConnectInterval","20000"));
		iMaxPageConnectInterval = (interval > 600000)?600000:interval;
//--*************************Modify by ShengMeng Bai at 2004-07-27		
		
		int timeout = Integer.parseInt(pro.getProperty("iaa.searchProcessTimeout","300"));
		SearchProcessTimeout = (timeout < 300)?300:timeout;

		int lineOfLog = Integer.parseInt(pro.getProperty("iaa.maxLineOfLog","5000"));
		MaxLineOfLog = (lineOfLog < 500)?500:lineOfLog;
		
		int imageSize = Integer.parseInt(pro.getProperty("iaa.maxImageSize","50000"));
		MaxImageSize = (imageSize < 5000)?5000:imageSize;
	//++Add by ShengMeng Bai at 2004-11-09
		imageSize = Integer.parseInt(pro.getProperty("iaa.minImageWidth","30"));
		m_iMinImageWidth = (imageSize < 0)?0:imageSize;
		imageSize = Integer.parseInt(pro.getProperty("iaa.minImageHeight","30"));
		m_iMinImageHeight = (imageSize < 0)?0:imageSize;
	//--Add by ShengMeng Bai at 2004-11-09
//++ Add by ShengMeng Bai for flash at 2004-07-23
		int iFlashSize = Integer.parseInt(pro.getProperty("iaa.maxFlashSize","100000"));
		MaxFlashSize = (iFlashSize < 10000)?10000:iFlashSize;
//-- Add by ShengMeng Bai for flash at 2004-07-23
//++ Add by ShengMeng Bai for simulate human at 2004-07-27
		boolean bCrawlTime = Boolean.valueOf(
				pro.getProperty("iaa.appointCrawlTime","false")).booleanValue();
		String sStartTime = pro.getProperty("iaa.crawlStartTime", "08:00:00");
		String sEndTime = pro.getProperty("iaa.crawlEndTime", "18:00:00");

		Time timeStart;
		Time timeEnd;
		try{
			timeStart = Time.valueOf(sStartTime);
			timeEnd = Time.valueOf(sEndTime);			
		} catch (IllegalArgumentException e){
			IaaUtil.log( "!!!!!!!Notice: iaa.crawlStartTime or iaa.crawlStartTime is unexcepted format. it will be set to default value.");
			timeStart = Time.valueOf("08:00:00");
			timeEnd = Time.valueOf("18:00:00");			
		}
		timeCrawlStartTime = timeStart;
		timeCrawlEndTime = timeEnd;
		if (bCrawlTime){
			if (timeCrawlEndTime.getHours() < timeCrawlStartTime.getHours()){
				bAppointCrawlTime = false;
				IaaUtil.log( "!!!!!!!Notice: iaa.crawlStartTime is bigger than iaa.crawlStartTime, system will be set iaa.appointCrawlTime to false.");
			} else if (timeCrawlEndTime.getHours() == timeCrawlStartTime.getHours() &&
					timeCrawlEndTime.getMinutes() < timeCrawlStartTime.getMinutes()){
					bAppointCrawlTime = false;
					IaaUtil.log( "!!!!!!!Notice: iaa.crawlStartTime is bigger than iaa.crawlStartTime, system will be set iaa.appointCrawlTime to false.");
			} else {
				bAppointCrawlTime = true;
				IaaUtil.log( "iaa.appointCrawlTime equal true, system will dispatch spider between "
						+ timeCrawlStartTime.toString() + " and " + timeCrawlEndTime.toString());
			}
		} else {
			bAppointCrawlTime = false;
		}
//-- Add by ShengMeng Bai for simulate human at 2004-07-27
//++ Add by ShengMeng Bai for proxy server at 2004-09-24
//		m_bProxySet = Boolean.valueOf(pro.getProperty("iaa.proxy","false")).booleanValue();
//		m_sProxyHost = pro.getProperty("iaa.proxyHost","127.0.0.1");
//		m_sProxyPort = pro.getProperty("iaa.proxyPort","8088");
//		m_sProxyUserName = pro.getProperty("iaa.proxyUserName","anonymous");
//		m_sProxyPassword = pro.getProperty("iaa.proxyPassword","anonymous");
		m_bRandomProxy = Boolean.valueOf(pro.getProperty("iaa.randomProxy","false")).booleanValue();
		int iTemp = Integer.parseInt(pro.getProperty("iaa.proxyExpireSeconds", "60"));
		if(iTemp < 1){
		    m_iProxyExpireSeconds = 60;
		}else{
		    m_iProxyExpireSeconds = iTemp;
		}
//-- Add by ShengMeng Bai for proxy server at 2004-09-24
		
//++ Add by ShengMeng Bai for parallel process impression at 2004-11-18
		iTemp = Integer.parseInt(pro.getProperty("iaa.spiderAuxThread","5"));
	//++deleted by changsheng at 2007-3-14
		/*if(iTemp > 10 ){
			iTemp = 10;
		}else if(iTemp < 2){
			iTemp = 2;
		}*/
	//--deleted by changsheng at 2007-3-14
		m_iSpiderAuxThread = iTemp;
//-- Add by ShengMeng Bai for parallel process impression at 2004-11-18


//++ Add by ShengMeng Bai for bad url at 2004-11-18
/*
 		iTemp = Integer.parseInt(pro.getProperty("iaa.reConnectInterval","12"));
		if(iTemp > 24*30 ){
			iTemp = 24*30;
		}else if(iTemp < 1){
			iTemp = 1;
		}
		m_iReConnectionInterval = iTemp;
		iTemp = Integer.parseInt(pro.getProperty("iaa.reConnectMaxTimes","5"));
		if(iTemp < 2){
			iTemp = 2;
		}
		m_iReConnectionTimes = iTemp;
*/
//-- Add by ShengMeng Bai for bad url at 2004-11-18
		LogDirectory = pro.getProperty("iaa.logDirectory","log");
		
//++ Add by ShengMeng Bai for bad url at 2005-04-30
		String sRobot = pro.getProperty("iaa.robotName","*").trim();
		if(sRobot.equals("")){
		    m_robotName = "*";
		}else{
		    m_robotName = sRobot;
		}
//-- Add by ShengMeng Bai for bad url at 2005-04-30
		
		//++changsheng for smart download 2006-5-16
		SmartDownloadCounterMax = 
			Integer.parseInt( pro.getProperty("SmartDownloadCounterMax","0")) ;
		pageAnalyzeTimeOut = Long.parseLong( pro.getProperty("iaa.pageAnalyzeTimeOut","120000"));
	}
	
	public static void say(int level, String s) {
		switch (level)  {
			case 1: if(AuxDebug)systemout.println(s);
					break;
			case 3:	if(ProDebug)systemout.println(s);
					break;
			case 5: if(Debug)systemout.println(s);
					break;
			case 7: if(DatabaseDebug)systemout.println(s);
					break;
			default :
				systemout.println(s);
		}
	}
	
	public static void say(String s) {
		say(3,s);
	}
	
	public static void boldSay(String s)  {
		say(3,".............................");
		say(3,"    --------  " + s + "  --------       ");
		say(3,".............................");
	}
	
	public static void begin(int level, String s) {
		say(level, "BEGIN: " + s);
	}
	
	public static void begin(String s) {
		timestamp("BEGIN: " +  s);
	}

	public static void end(int level, String s) {
		say(level, "END: " + s);
	}

	public static void end(String s) {
		timestamp("END: " +  s);
	}
	
	public static void timestamp(String s)
	{
	    if(ProDebug)systemout.println("[" + new Timestamp(System.currentTimeMillis()) + "] " + s);
	}
	
	public static void assert_6(boolean flag)
	{
	    if(!flag)
	        throw new RuntimeException("Assertion violated");
	    else
	        return;
	}
	
	public static void assert_6(boolean flag, String s)
	{
	    if(!flag)
	        throw new RuntimeException(s);
	    else
	        return;
	}	
}


